package com.mf.basic.services;

import cn.dev33.satoken.stp.StpUtil;
import com.mf.basic.entity.DtoUser;
import com.mf.basic.mapper.MapperUserRole;
import com.mf.basic.entity.DtoUserRole;
import com.mf.basic.enums.EnumBaseParams;
import com.mf.basic.exceptions.MyException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Created by Luke on 2025/3/7 17:06.
 */
@Service
@Transactional
public class ServiceUserRole extends ServiceImpl<MapperUserRole, DtoUserRole> implements BaseService<DtoUserRole>{

    @Override
    public LambdaQueryWrapper<DtoUserRole> fillParams(Map<String, Object> params) {
        return null;
    }

    @Resource
    private ServiceRole serviceRole;
    @Resource
    private ServiceUser serviceUser;

    /**
     * 添加角色用户关联信息:覆盖模式
     * @param roleId 角色ID
     * @param userIds 用户IDs
     */
    public synchronized void doAddByCover(Long roleId, String userIds) {
        //验证角色ID是否合法
        serviceRole.findCheckById(Math.toIntExact(roleId), true);
        //查询用户IDs信息, 防止无效的用户ID
        Set<Integer> userIdSet;
        try {
            userIdSet = idsToSet(userIds);
        }catch (Exception e){
            throw new MyException("用户IDs("+userIds+")错误, 请检查");
        }
        //如果角色为管理员, 则默认添加超级管理员用户
        if(roleId == 1){
            userIdSet.add(1);
        }
        List<DtoUser> userList = serviceUser.getBaseMapper().selectBatchIds(userIdSet);
        Assert.state(userList.size() == userIdSet.size(), "用户IDs信息错误, 请检查");
        //删除角色下的旧的用户角色关联信息
        LambdaQueryWrapper<DtoUserRole> qw = loadQw();
        qw.eq(DtoUserRole::getRoleId, roleId);
        List<DtoUserRole> delList = this.list(qw);
        if(!CollectionUtils.isEmpty(delList)){
            this.removeBatchByIds(delList);
        }
        //添加新的用户角色关联信息
        List<DtoUserRole> addList = new ArrayList<>();
        String douser = (String) StpUtil.getSession().get(EnumBaseParams.douser.name());
        for(DtoUser user : userList){
            addList.add(new DtoUserRole()
                    .setUserId(user.getId())
                    .setRoleId(roleId)
                    .setDouser(douser));
        }
        this.saveBatch(addList);
    }

    /**
     * 添加角色用户关联信息-追加模式
     * @param roleId 角色ID
     * @param userIds 用户IDs
     */
    public synchronized void doAddByAppend(Long roleId, String userIds) {
        //验证角色ID是否合法
        serviceRole.findCheckById(Math.toIntExact(roleId), true);
        //查询用户IDs信息, 防止无效的用户ID
        Set<Integer> userIdSet;
        try {
            userIdSet = idsToSet(userIds);
        }catch (Exception e){
            throw new MyException("用户IDs("+userIds+")错误, 请检查");
        }
        //如果角色为管理员, 则默认添加超级管理员用户
        if(roleId == 1){
            userIdSet.add(1);
        }
        List<DtoUser> userList = serviceUser.getBaseMapper().selectBatchIds(userIdSet);
        Assert.state(userList.size() == userIdSet.size(), "用户IDs信息错误, 请检查");
        //查询该角色下已有的用户, 用于判断防止重复添加
        List<DtoUserRole> hisList = findByRoleId(roleId);
        Set<Long> hisSet = new HashSet<>();
        if(!CollectionUtils.isEmpty(hisList)){
            for(DtoUserRole userRole : hisList){
                hisSet.add(userRole.getUserId());
            }
        }
        //添加新的用户角色关联信息
        List<DtoUserRole> addList = new ArrayList<>();
        String douser = (String) StpUtil.getSession().get(EnumBaseParams.douser.name());
        for(DtoUser user : userList){
            if(hisSet.contains(user.getId())){
                continue;
            }
            addList.add(new DtoUserRole()
                    .setUserId(user.getId())
                    .setRoleId(roleId)
                    .setDouser(douser));
        }
        this.saveBatch(addList);
    }

    /**
     * 删除角色用户关联信息
     * @param roleId 角色ID
     * @param userIds 用户IDs
     */
    public synchronized void doDelete(Long roleId, String userIds) {
        //验证角色ID是否合法
        serviceRole.findCheckById(Math.toIntExact(roleId), true);
        //查询用户IDs信息, 防止无效的用户ID
        Set<Integer> userIdSet;
        try {
            userIdSet = idsToSet(userIds);
        }catch (Exception e){
            throw new MyException("用户IDs("+userIds+")错误, 请检查");
        }
        //如果角色为管理员, 则默认添加超级管理员用户
        if(roleId == 1){
            Assert.state(userIdSet.contains(1), "您不能删除超级管理员用户, 请检查");
        }
        List<DtoUser> userList = serviceUser.getBaseMapper().selectBatchIds(userIdSet);
        Assert.state(userList.size() == userIdSet.size(), "用户IDs信息错误, 请检查");
        this.remove(loadQw()
                .eq(DtoUserRole::getRoleId, roleId)
                .in(DtoUserRole::getUserId, userIdSet));
    }

    /**
     * 根据角色ID查询用户角色关联信息
     * @param roleId 角色ID
     * @return List<DtoUserRole>
     */
    public List<DtoUserRole> findByRoleId(Long roleId) {
        return this.list(loadQw().eq(DtoUserRole::getRoleId, roleId));
    }

}
